package com.ruoyi.basicsystem.service.impl;

import java.math.BigDecimal;
import java.util.*;

import com.ruoyi.basicsystem.domain.*;
import com.ruoyi.basicsystem.mapper.ZnAccountItemMapper;
import com.ruoyi.basicsystem.mapper.ZnSupplierMapper;
import com.ruoyi.bill.domain.ZnDepotHead;
import com.ruoyi.bill.domain.ZnDepotItem;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.constant.BusinessConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.RedisConstant;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.basicsystem.mapper.ZnAccountHeadMapper;
import com.ruoyi.basicsystem.service.IZnAccountHeadService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 财务主Service业务层处理
 * 
 * @author ruoyi
 * @date 2022-02-23
 */
@Service
public class ZnAccountHeadServiceImpl implements IZnAccountHeadService 
{
    @Autowired
    private ZnAccountHeadMapper znAccountHeadMapper;
    @Autowired
    private ZnAccountItemMapper znAccountItemMapper;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ZnSupplierMapper znSupplierMapper;

    /**
     * 查询财务主
     * 
     * @param id 财务主主键
     * @return 财务主
     */
    @Override
    public ZnAccountHead selectZnAccountHeadById(Long id)
    {
        return znAccountHeadMapper.selectZnAccountHeadById(id);
    }

    /**
     * 查询财务主列表
     * 
     * @param znAccountHead 财务主
     * @return 财务主
     */
    @Override
    public List<ZnAccountHead> selectZnAccountHeadList(ZnAccountHead znAccountHead)
    {
        return znAccountHeadMapper.selectZnAccountHeadList(znAccountHead);
    }
     /**
      * 查询财务主记录数
      *
      * @param znAccountHead 财务主
      * @return 财务主记录数
     */
    public Integer selectZnAccountHeadCount(ZnAccountHead znAccountHead){
        return znAccountHeadMapper.selectZnAccountHeadCount(znAccountHead);
    }


    /**
     * 新增财务主
     * 
     * @param znAccountHead 财务主
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @RepeatSubmit
    public int insertZnAccountHead(ZnAccountHead znAccountHead)
    {
        Date date = DateUtils.getNowDate();
        znAccountHead.setCreateTime(date);
//        znAccountHead.setBillTime(date);
        znAccountHead.setCreator(SecurityUtils.getUserId());
        znAccountHead.setTenantId(SecurityUtils.getTenantId());
        znAccountHead.setDeleteFlag("0");
        znAccountHead.setStatus("0");
        if(BusinessConstants.ACCOUNTHEAD_TYPE_SR.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_ZC.equals(znAccountHead.getType())){
           if(znAccountHead.getChangeAmount()==null){
               znAccountHead.setChangeAmount(BigDecimal.ZERO.subtract(znAccountHead.getTotalPrice()));
           }
        }
        //转账、支出、付款、期初应付
        if(BusinessConstants.ACCOUNTHEAD_TYPE_ZZ.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_ZC.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_FK.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_QCYF.equals(znAccountHead.getType())){
            znAccountHead.setTotalPrice(BigDecimal.ZERO.subtract(znAccountHead.getTotalPrice()));
            znAccountHead.setChangeAmount(BigDecimal.ZERO.subtract(znAccountHead.getChangeAmount()));
        }
        if(BusinessConstants.ACCOUNTHEAD_TYPE_QCYF.equals(znAccountHead.getType())){
            ZnSupplier znSupplier = new ZnSupplier();
            znSupplier.setId(znAccountHead.getOrganId());
            ZnSupplier temp = znSupplierMapper.selectZnSupplierById(znAccountHead.getOrganId());
            if(temp.getBeginNeedPay().compareTo(znAccountHead.getZnAccountItemList().get(0).getEachAmount())>=0){
                znSupplier.getParams().put("qcyf",znAccountHead.getZnAccountItemList().get(0).getEachAmount());
                znSupplierMapper.updateZnSupplier(znSupplier);
            }else{
                return -2;
            }

        }
        if(BusinessConstants.ACCOUNTHEAD_TYPE_QCYS.equals(znAccountHead.getType())){
            ZnSupplier znSupplier = new ZnSupplier();
            znSupplier.setId(znAccountHead.getOrganId());
            ZnSupplier temp = znSupplierMapper.selectZnSupplierById(znAccountHead.getOrganId());
            if(temp.getBeginNeedGet().compareTo(znAccountHead.getZnAccountItemList().get(0).getEachAmount())>=0){
                znSupplier.getParams().put("qcys",znAccountHead.getZnAccountItemList().get(0).getEachAmount());
                znSupplierMapper.updateZnSupplier(znSupplier);
            }else{
                return -1;
            }
        }
        int rows = znAccountHeadMapper.insertZnAccountHead(znAccountHead);
        insertZnAccountItem(znAccountHead);
        return rows;
    }
    /**
     * 新增单据子信息
     *
     * @param znAccountHead 单据管理对象
     */
    public void insertZnAccountItem(ZnAccountHead znAccountHead)
    {
        List<ZnAccountItem> znAccountItemList = znAccountHead.getZnAccountItemList();
        Long id = znAccountHead.getId();
        if (StringUtils.isNotNull(znAccountItemList))
        {
            List<ZnAccountItem> list = new ArrayList<ZnAccountItem>();
            BigDecimal yfk = BigDecimal.ZERO;
            List<ZnAccountItem> insterList = new ArrayList<>();
            List<ZnAccountItem> updateList = new ArrayList<>();

            for (ZnAccountItem znAccountItem : znAccountItemList)
            {
                znAccountItem.setHeaderId(id);
                znAccountItem.setTenantId(znAccountHead.getTenantId());
                znAccountItem.setDeleteFlag("0");
                list.add(znAccountItem);
                if(znAccountItem.getId()==null){
                    insterList.add(znAccountItem);
                    yfk = yfk.add(znAccountItem.getEachAmount());
                }else{
                    updateList.add(znAccountItem);
                    if(BusinessConstants.PAY_TYPE_PREPAID.equals(znAccountHead.getType())){//（收）预付款
                        ZnAccountItem temp = znAccountItemMapper.selectZnAccountItemById(znAccountItem.getId());
                        if(temp.getEachAmount().doubleValue()!=znAccountItem.getEachAmount().doubleValue()){//订单金额有变化的情况下
                            yfk = yfk.add(temp.getEachAmount().subtract(znAccountItem.getEachAmount()));
                        }
                    }
                }
            }
            if (insterList.size() > 0)
            {
                //是否收预付款，更新会员的授信的预付款金额
                if(BusinessConstants.PAY_TYPE_PREPAID.equals(znAccountHead.getType()) && yfk !=BigDecimal.ZERO){
                    ZnSupplier znSupplier = new ZnSupplier();
                    znSupplier.setId(znAccountHead.getOrganId());
                    Map<String,Object> params =new HashMap();
                    params.put("advanceIn", yfk);
                    params.put("updateType", "+");
                    znSupplier.setParams(params);
                    znSupplierMapper.updateZnSupplier(znSupplier);
                }
                    znAccountItemMapper.batchZnAccountItem(insterList);
            }
            if(updateList.size()>0){
                for (ZnAccountItem item:updateList) {
                    znAccountItemMapper.updateZnAccountItem(item);
                }
            }
        }
    }
    /**
     * 修改财务主
     * 
     * @param znAccountHead 财务主
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateZnAccountHead(ZnAccountHead znAccountHead)
    {
        if(BusinessConstants.ACCOUNTHEAD_TYPE_SR.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_ZC.equals(znAccountHead.getType())){
            if(znAccountHead.getChangeAmount()==null){
                znAccountHead.setChangeAmount(BigDecimal.ZERO.subtract(znAccountHead.getTotalPrice()));
            }
        }
        if(BusinessConstants.ACCOUNTHEAD_TYPE_ZZ.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_ZC.equals(znAccountHead.getType()) || BusinessConstants.ACCOUNTHEAD_TYPE_FK.equals(znAccountHead.getType())){
            znAccountHead.setTotalPrice(BigDecimal.ZERO.subtract(znAccountHead.getTotalPrice()));
            znAccountHead.setChangeAmount(BigDecimal.ZERO.subtract(znAccountHead.getChangeAmount()));
        }
        if(BusinessConstants.ACCOUNTHEAD_TYPE_QCYF.equals(znAccountHead.getType())){
            ZnSupplier znSupplier = new ZnSupplier();
            znSupplier.setId(znAccountHead.getOrganId());
            ZnSupplier temp = znSupplierMapper.selectZnSupplierById(znAccountHead.getOrganId());
            ZnAccountHead znAccountHead1 = znAccountHeadMapper.selectZnAccountHeadCulItemById(znAccountHead.getId());
            if(temp.getBeginNeedPay().compareTo(znAccountHead.getZnAccountItemList().get(0).getEachAmount().subtract(znAccountHead1.getZnAccountItemList().get(0).getEachAmount()).abs())>=0){
                znSupplier.getParams().put("qcyf",znAccountHead.getZnAccountItemList().get(0).getEachAmount());
                znSupplierMapper.updateZnSupplier(znSupplier);
            }else{
                return -2;
            }

        }
        if(BusinessConstants.ACCOUNTHEAD_TYPE_QCYS.equals(znAccountHead.getType())){
            ZnSupplier znSupplier = new ZnSupplier();
            znSupplier.setId(znAccountHead.getOrganId());
            ZnSupplier temp = znSupplierMapper.selectZnSupplierById(znAccountHead.getOrganId());
            ZnAccountHead znAccountHead1 = znAccountHeadMapper.selectZnAccountHeadCulItemById(znAccountHead.getId());
            if(temp.getBeginNeedGet().compareTo(znAccountHead.getZnAccountItemList().get(0).getEachAmount().subtract(znAccountHead1.getZnAccountItemList().get(0).getEachAmount()).abs())>=0){
                znSupplier.getParams().put("qcys",znAccountHead.getZnAccountItemList().get(0).getEachAmount());
                znSupplierMapper.updateZnSupplier(znSupplier);
            }else{
                return -1;
            }
        }
        znAccountItemMapper.deleteZnAccountItemByHeadId(znAccountHead.getId());
        insertZnAccountItem(znAccountHead);
        return znAccountHeadMapper.updateZnAccountHead(znAccountHead);
    }

    /**
     * 批量删除财务主
     * 
     * @param ids 需要删除的财务主主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteZnAccountHeadByIds(Long[] ids)
    {
//        return znAccountHeadMapper.deleteZnAccountHeadByIds(ids);
        int rows =  znAccountItemMapper.deleteZnAccountItemByHeadIds(ids);
        if(rows>0){
            rows = znAccountHeadMapper.deleteZnAccountHeadByIds(ids);
        }else{
            throw new ServiceException("删除财务单据异常");
        }
        return rows;
    }

    /**
     * 删除财务主信息
     * 
     * @param id 财务主主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteZnAccountHeadById(Long id)
    {
        int rows =  znAccountItemMapper.deleteZnAccountItemByHeadId(id);
        if(rows>0){
            rows = znAccountHeadMapper.deleteZnAccountHeadById(id);
        }else{
            throw new ServiceException("删除财务单据异常");
        }
        return rows;
    }

    @Override
    public List<AccountHeadVo4ListEx> getDetailByNumber(String billNo) {
        List<AccountHeadVo4ListEx> resList = new ArrayList<AccountHeadVo4ListEx>();
        List<AccountHeadVo4ListEx> list = null;
        list = znAccountHeadMapper.getDetailByNumber(billNo);

        if (null != list) {
            for (AccountHeadVo4ListEx ah : list) {
                if(ah.getChangeAmount() != null) {
                    ah.setChangeAmount(ah.getChangeAmount().abs());
                }
                if(ah.getTotalPrice() != null) {
                    ah.setTotalPrice(ah.getTotalPrice().abs());
                }
                ah.setBillTimeStr(DateUtils.getCenternTime(ah.getBillTime()));
                resList.add(ah);
            }
        }
        return resList;
    }

    @Override
    public int changeStatus(Long[] ids, String status) {
        return znAccountHeadMapper.changeStatus(ids,status);
    }

    /**
     * 获取单据编号
     * @param  type 1 零售(0出库[LSCK]、1退货[LSTH]) 2销售（0订单[SSDD] 1出库[SSCK] 2退货[SSTH]） 3 采购（0订单[CGDD] 1出库[CGCK] 2退货[CGTH]） 5其它（0入库[QTRK] 1出库[QTCK] 2调拨出库[DBCK] 3组装单[ZZDD] 4拆卸单[CXDD]） 为文字拼音的首字母
     */
    @Override
    public String getAccountNo(String type) {
        Long buildOnlyNumber=null;
        String result = "";
        synchronized (this){
            String key =  RedisConstant.ACCOUNT_NO  +"_" + type;
            Long retailNo = redisCache.getCacheObject(key);
            if(retailNo ==null){
                buildOnlyNumber = 1l;
            }else{
                buildOnlyNumber = retailNo;
            }
            redisCache.setCacheObject(key,buildOnlyNumber+1);
            if(buildOnlyNumber< Constants.SEQ_TO_STRING_MIN_LENGTH){
                StringBuffer sb=new StringBuffer(buildOnlyNumber.toString());
                int len=Constants.SEQ_TO_STRING_MIN_LENGTH.toString().length()-sb.length();
                for(int i=0;i<len;i++){
                    sb.insert(0,Constants.SEQ_TO_STRING_LESS_INSERT);
                }
                result =  type + sb.toString();
            }else{
                result =  type + buildOnlyNumber.toString();
            }
            if(redisCache.getCacheSet(RedisConstant.USED_ACCOUNT_NO  +"_" + type).contains(result)){
                getAccountNo(type);
            }
        }
        return result;
    }

    @Override
    public ZnAccountHead selectZnAccountHeadCulItemById(Long id) {
        return znAccountHeadMapper.selectZnAccountHeadCulItemById(id);
    }

    @Override
    public List<ZnAccountHeadExportVo> selectZnAccountHeadExportList(ZnAccountHead znAccountHead) {
        return znAccountHeadMapper.selectZnAccountHeadExportList(znAccountHead);
    }

    @Override
    public Map<String, BigDecimal> selectZnAccountHeadQC(ZnDepotHead znDepotHead) {
        return znAccountHeadMapper.selectZnAccountHeadQC(znDepotHead);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteZnAccountHeadQcByIds(Long[] ids) {
        int update = znSupplierMapper.backNeedMoney(ids);
        int rows =  znAccountItemMapper.deleteZnAccountItemByHeadIds(ids);
        if(rows>0 && update>0){
            rows = znAccountHeadMapper.deleteZnAccountHeadByIds(ids);
        }else{
            throw new ServiceException("删除财务单据异常");
        }
        return rows;
    }

}
